package com.cloudlead.utils.async;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 异步任务线程执行器
 *
 * @Description 异步任务线程执行器
 * 
 * @date 2014年7月18日 上午11:30:03
 * @author 陆林(lulin@cloudlead-partners.com)
 * @version 2.0
 * @since 2.0
 */
public class AsyncTaskThreadPoolExecutor extends ThreadPoolExecutor {

	private final AtomicLong executingTaskNum;

	private final AtomicLong executedTaskNum;

	/**
	 * 
	 * <p>
	 * Title:
	 * </p>
	 * <p>
	 * Description: Creates a new instance of AsyncTaskThreadPoolExecutor.
	 * </p>
	 * 
	 * @param corePoolSize
	 * @param maximumPoolSize
	 * @param keepAliveTime
	 * @param unit
	 * @param workQueue
	 * @param threadFactory
	 * @param executingTaskNum
	 * @param executedTaskNum
	 */
	public AsyncTaskThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
			AtomicLong executingTaskNum, AtomicLong executedTaskNum) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
				threadFactory);
		this.executingTaskNum = executingTaskNum;
		this.executedTaskNum = executedTaskNum;
	}

	/**
	 * 
	 * <p>
	 * Title:
	 * </p>
	 * <p>
	 * Description: Creates a new instance of AsyncTaskThreadPoolExecutor.
	 * </p>
	 * 
	 * @param corePoolSize
	 * @param maximumPoolSize
	 * @param keepAliveTime
	 * @param unit
	 * @param workQueue
	 * @param threadFactory
	 * @param handler
	 * @param executingTaskNum
	 * @param executedTaskNum
	 */
	public AsyncTaskThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
			long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
			RejectedExecutionHandler handler, AtomicLong executingTaskNum,
			AtomicLong executedTaskNum) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
				threadFactory, handler);
		this.executingTaskNum = executingTaskNum;
		this.executedTaskNum = executedTaskNum;
	}

	@Override
	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		executedTaskNum.incrementAndGet();
		executingTaskNum.getAndDecrement();
	}

	@Override
	protected void beforeExecute(Thread t, Runnable r) {
		super.beforeExecute(t, r);
		executingTaskNum.incrementAndGet();
	}

	@Override
	protected void terminated() {
		super.terminated();
	}

}
